from abc import ABC, abstractmethod

import requests

from user.models import OAuthUser, User
from user.serial import UserRegisterSerializer, OAuthUserSerializer


# 定义抽象工厂
class Product(ABC):
    @abstractmethod
    def get_url(self):
        pass

    @abstractmethod
    def callback(self, **kwargs):
        pass

class DingdingLogin(Product):

    def get_url(self):
        from urllib.parse import quote
        params = [
            f"redirect_uri={quote('http://127.0.0.1:8080/dingtalkCallback/?types=dingding')}",
            "response_type=code",
            "client_id=dingvcyxcogdqrstxgk7",
            "scope=openid",
            "prompt=consent"
        ]
        url = "https://login.dingtalk.com/oauth2/auth?" + ("&".join(params))
        print(url)
        return url

    def callback(self, **kwargs):
        authcode = kwargs.get('authcode')
        print("authcode:", authcode)

        # 根据authCode获取用户accessToken
        data = {
            "clientId": "dingvcyxcogdqrstxgk7",
            "clientSecret": "Pli_ZL5lJyl52u4Mkh6B0gUJtX-2ihDTwGvxB-bXYdukfDMbdqe0h2cMogqk8aXW",
            "code": authcode,
            "grantType": "authorization_code"
        }
        resp = requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken', json=data).json()
        print("钉钉返回的userAccessToken：", resp)
        accessToken = resp.get('accessToken')

        # 根据accessToken获取用户信息
        headers = {"x-acs-dingtalk-access-token": accessToken}
        resp = requests.get('https://api.dingtalk.com/v1.0/contact/users/me', headers=headers).json()
        print("钉钉返回的用户信息：", resp)

        name = resp.get('nick')
        uid = resp.get('openId')
        mobile = resp.get('mobile')

        # 登录，写入三方登录表和用户表
        # 判断该用户是否已经使用该第三方登录注册过
        oauth = OAuthUser.objects.filter(uid=uid, type=1).first()
        if not oauth:
            # 写入用户表
            # 手机号用户存在直接绑定,不存在注册新用户
            user = User.objects.filter(mobile=mobile).first()
            print(user)
            if not user:
                userinfo = {
                    "name": name,
                    "mobile": mobile,
                    "password": "123456",
                }
                user_ser = UserRegisterSerializer(data=userinfo)
                if user_ser.is_valid():
                    user = user_ser.save()
                else:
                    return {"code": 10001, "msg": user_ser.errors}
            # 写入三方登录表
            oath_userinfo = {
                "type": 1,
                "token": accessToken,
                "uid": uid,
                "user": user.id
            }
            print(oath_userinfo)
            oath_ser = OAuthUserSerializer(data=oath_userinfo)
            if oath_ser.is_valid():
                print("11111111111111")
                oath_ser.save()
            else:
                return {"code": 10001, "msg": oath_ser.errors}
        # 如果已经注册
        else:
            user = oauth.user
            oauth.token = accessToken
            oauth.save()

        # 生成jwt token并返回前端
        # payload = {"userid": user.id, "username": user.username, "exp": int(time.time()) + 60 * 60 * 2}
        # token = myjwt.jwt_encode(payload)
        # payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
        # refreshToken = myjwt.jwt_encode(payload)
        # query = [f"userid={payload['userid']}", f"username={payload['username']}", f"token={token}",
        #          f"refreshToken={refreshToken}"]
        return {"code": 200, "msg": "登录成功", "data": {"token": accessToken}}

class WechatLogin(Product):
    def get_url(self):
        return "https://open.weixin.qq.com/connect/qrconnect?appid=wx789a"

    def callback(self, **kwargs):
        return "https://www.wechat.com/"


class Factory:
    def create_factory(self, params):
        # getattr  setattr
        if params == 'dingding':
            return DingdingLogin()

        elif params == 'weibo':
            return WechatLogin()

